package nayasis.common.ui.javaFx.dialog;

import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.stage.Window;

/**
 * Dialog Manager
 * 
 * @author Anton Smirnov (dev@antonsmirnov.name)
 * @modified by nayasis (nayasis@gmail.com)
 */
public class DialogManager extends Stage {

	private final int    MESSAGE_MIN_WIDTH = 180;
    private final int    MESSAGE_MAX_WIDTH = 800;
    private final int    BUTTON_WIDTH = 60;
    private final double MARGIN = 10;
	
	private VBox       messageBox;
	private Label      messageLabel;
	private BorderPane borderPanel;
	private ImageView  icon;
	private Scene      scene;

	private Image iconBug     = new Image( getClass().getResourceAsStream("iconBug.png")     );
	private Image iconConfirm = new Image( getClass().getResourceAsStream("iconConfirm.png") );
	private Image iconError   = new Image( getClass().getResourceAsStream("iconError.png")   );
	private Image iconInfo    = new Image( getClass().getResourceAsStream("iconInfo.png")    );
	private Image iconWarning = new Image( getClass().getResourceAsStream("iconWarning.png") );
	
	private HBox       buttonsPanel;
	
    public DialogManager() {
    	init();
    }

    private void init() {

    	this.setResizable( false );
    	this.initStyle( StageStyle.UTILITY );
    	this.initModality( Modality.APPLICATION_MODAL );                        
    	this.setIconified( false );
    	this.centerOnScreen();
    	
    	this.icon = new ImageView();

    	this.borderPanel = new BorderPane();
    	this.borderPanel.setLeft( this.icon );
        BorderPane.setMargin( this.icon, new Insets(MARGIN) );
    	
    	this.messageBox = new VBox();
    	this.messageBox.setAlignment( Pos.CENTER_LEFT );

        this.messageLabel = new Label();
        this.messageLabel.setWrapText( true );
        this.messageLabel.setMinWidth( MESSAGE_MIN_WIDTH );
        this.messageLabel.setMaxWidth( MESSAGE_MAX_WIDTH );

        this.messageBox.getChildren().add( this.messageLabel );
        this.borderPanel.setCenter( this.messageBox );

        BorderPane.setAlignment( this.messageBox, Pos.CENTER );
        BorderPane.setMargin( this.messageBox, new Insets(MARGIN, MARGIN, MARGIN, 2 * MARGIN) );

        
        // buttons
        this.buttonsPanel = new HBox();
        this.buttonsPanel.setSpacing( MARGIN );
        this.buttonsPanel.setAlignment( Pos.BOTTOM_CENTER );
        BorderPane.setMargin( this.buttonsPanel, new Insets(0, 0, 1.5 * MARGIN, 0) );
        this.borderPanel.setBottom( this.buttonsPanel );
        this.borderPanel.widthProperty().addListener(new ChangeListener<Number> () {

            public void changed(ObservableValue<? extends Number> ov, Number t, Number t1) {
            	buttonsPanel.layout();
            }
            
        });

        scene = new Scene( borderPanel );
        this.setScene( scene );

    }

    public void setOwner( Window owner ) {
    	
    	if( owner == null ) return;

        this.initOwner( owner );
        this.borderPanel.setMaxWidth( owner.getWidth() );
        this.borderPanel.setMaxHeight( owner.getHeight() );
    	
    }

    public void setTitle( Object title ) {
    	this.setTitle( title );
    }
    
    public void setMessage( Object message ) {
    	this.messageLabel.setText( message == null ? "" : message.toString() );
    }

//    private void alignScrollPane() {
//        this.setWidth( this.icon.getImage().getWidth() + this.messageLabel.getWidth() + 5 * MARGIN );
//            
//        this.setHeight( Math.max(
//        	this.icon.getImage().getHeight(), 
//        	this.messageLabel.getHeight() +
//        	this.buttonsPanel.getHeight() + 3 * MARGIN
//        ));
//            
//        this.centerOnScreen();
//    }

    public void setIconWarning() {
    	this.icon.setImage( iconWarning );
    }
    public void setIconError() {
    	this.icon.setImage( iconError );
    }
    public void setIconThrowable() {
    	this.icon.setImage( iconBug );
    }
    public void setIconConfirm() {
    	this.icon.setImage( iconConfirm );
    }
    public void setIconInfo() {
    	this.icon.setImage( iconInfo );
    }

    private void selfHide() {
    	this.hide();
    	buttonsPanel.getChildren().clear();
    }

    public void addButton( String caption, final EventHandler actionHandler ) {

    	Button button = new Button( caption );
        button.setMinWidth( BUTTON_WIDTH );
        button.setOnAction( new EventHandler<ActionEvent>() {

            public void handle( ActionEvent event ) {
            	selfHide();
                if (actionHandler != null) actionHandler.handle( event );
            }
        });
        
        buttonsPanel.getChildren().add( button );

    }

    public void addButton( String caption ) {
    	
    	addButton( caption, null );
    	
    }
    
    public void display( boolean wait ) {

        if ( buttonsPanel.getChildren().size() == 0 ) throw new RuntimeException("Add one dialog button at least");
        
        buttonsPanel.getChildren().get(0).requestFocus();
        
        if( wait ) {
        	this.showAndWait();
        } else {
        	this.show();
        	
        }

    }
    
}
